﻿using DevExpress.Mvvm;
using DevExpress.Mvvm.Native;
using HandyControl.Controls;
using PlaceOrder_Admin.Events;
using PlaceOrder_Admin.Models.Common;
using PlaceOrder_Core.Helper;
using PlaceOrder_Core.Models.QuanYi;
using PlaceOrder_Core.PlaceOrderModels;
using PlaceOrder_Core.Services.Interfaces;
using PlaceOrder_Shared.Models.Common;
using PlaceOrder_Shared.Models.Daily;
using PlaceOrder_Shared.Models.Trade;
using Prism.Commands;
using Prism.DryIoc;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.WebSockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using DelegateCommand = Prism.Commands.DelegateCommand;

namespace PlaceOrder_Admin.ViewModels
{
    /// <summary>
    /// 管理端，接收Server发来的所有websocket消息
    /// </summary>
    public class IndexAdminViewModel : Prism.Mvvm.BindableBase
    {
        private readonly IDailyData _dailyData;
        private readonly IUserHelper _userHelper;
        private ClientWebSocketHelper adminwebsocket;
        public static List<ChatReceiver> Receivers = new List<ChatReceiver>();
        public static Dictionary<int, string> UserInfo = new Dictionary<int, string>();
        private int CurrentDailyID = 0;
        private bool ServerIsConnected = false; // 连接服务端
        public DelegateCommand TestCommand { get; set; }
        private readonly IEventAggregator _eventAggregator;
        public IndexAdminViewModel(IDailyData dailyData, IEventAggregator eventAggregator, IUserHelper userHelper)
        {
            _eventAggregator = eventAggregator;
            _dailyData = dailyData;
            _userHelper = userHelper;
            InitValue();
            //AdminStartConnectionToServer();
        }

        private async void InitValue()
        {
            UserData = await Task.Run(() => _dailyData.GetAllUsers().ToObservableCollection());

            Trades = await Task.Run(() => _dailyData.GetUserTrades().ToObservableCollection());
            Receivers = _dailyData.GetChatReceivers();
            foreach (var user in UserData)
            {
                UserInfo[user.UserID] = user.NickName;
            }
            Greet();

        }



        #region 依赖属性
        private ObservableCollection<TradeSimUser> userData;
        public ObservableCollection<TradeSimUser> UserData
        {
            get => userData;
            set
            {
                if (userData != value)
                {
                    userData = value;
                    RaisePropertyChanged();
                }
            }
        }


        private ObservableCollection<UserTrade> trades;
        public ObservableCollection<UserTrade> Trades
        {
            get => trades;
            set
            {
                if (trades != value)
                {
                    trades = value;
                    RaisePropertyChanged();
                }
            }
        }
        #endregion

        public bool AdminStartConnectionToServer()
        {
            adminwebsocket = new ClientWebSocketHelper(_dailyData);
            adminwebsocket.ServerConnectedEvent += Adminwebsocket_ServerConnectedEvent;
            //adminwebsocket.ServerDisconnectedEvent += Adminwebsocket_ServerDisconnectedEvent;
            adminwebsocket.AdminMessageEvent += Adminwebsocket_AdminMessageEvent;
            adminwebsocket.QuanYiOrderServerToAdminMessageEvent += Adminwebsocket_QuanYiOrderServerToAdminMessageEvent;


            Messenger.Default.Register<QuanYiOrderServerResponseClass>(this, MessageToken.SendChatMessage, SendChatMessageToServer);
            string ServerIP = _dailyData.GetConfigs("WeChatServer")[0].Value;
            //string ServerIP
            if (adminwebsocket.AdminStartConnectToServer(ServerIP, 38889))
            {
                ServerIsConnected = true;
                Growl.SuccessGlobal("成功连接至服务端");
                return true;
            }
            else
            {
                ServerIsConnected = false;
                return false;
            }
        }

        /// <summary>
        /// 发送快捷消息至服务端
        /// </summary>
        /// <param name="class"></param>
        private void SendChatMessageToServer(QuanYiOrderServerResponseClass qsr)
        {
            try
            {
                if (adminwebsocket.SendResponseToServer(qsr))
                {
                    Growl.SuccessGlobal($"发送消息成功至服务端,内容{qsr.Message}");
                }
                else
                {
                    Growl.WarningGlobal($"发送消息至服务端失败,内容{qsr.Message}");
                }

            }
            catch (Exception ex)
            {
                Growl.WarningGlobal($"发送消息至服务端异常,内容{qsr.Message}+{ex.Message}");
                AppLog.WriteError($"发送消息至服务端异常,内容{qsr.Message}+{ex.Message}");
            }


        }

        private void Adminwebsocket_ServerDisconnectedEvent()
        {
            AppLog.WriteError("管理端连接不上服务端。");
        }

        private void Adminwebsocket_ServerConnectedEvent()
        {
            AppLog.WriteInfo("管理端与服务端成功连接");
        }

        private async void Adminwebsocket_QuanYiOrderServerToAdminMessageEvent(QuanYiOrderServerResponseClass QSR)
        {
            try
            {
                UserTrade tmpTrade;
                TradeSimUser user;
                ChatReceiver chat;
                int result;
                int UserTradeID;
                string msg;
                int ActualVolume;
                UserTrade ut;
                switch (QSR.DataType)
                {
                    case QuanYiServerBaseClass.DataTypeEnum.Login:
                        user = UserData.Single(x => x.UserID == QSR.UserID);
                        PrismApplication.Current.Dispatcher.Invoke(() =>
                        {
                            user.Status = 1;
                            user.LoginTime = DateTime.Now;
                        });
                        QSR.Code = 0;
                        QSR.Message = "OK";
                        if (user.UserStatus > SimTradeUserStatusEnmu.Normal)
                        {
                            QSR.Code = 0;
                            QSR.Message = ((int)user.UserStatus).ToString();
                            QSR.DataType = QuanYiServerBaseClass.DataTypeEnum.UserStatusChange;
                            QSR.Trade = new UserTrade();
                            QSR.Trade.Time = user.DisabledTime;
                        }
                        AppLog.WriteInfo($"新用户登录，用户名：{user.NickName},登录时间：{user.LoginTime}");
                        Growl.InfoGlobal($"新用户登录，用户名：{user.NickName},登录时间：{user.LoginTime}");
                        //serverWebSocketFromClient?.SendMessageToAdmin(QSR);
                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.Logout:

                        user = UserData.Single(x => x.UserID == QSR.UserID);
                        PrismApplication.Current.Dispatcher.Invoke(() =>
                        {
                            user.Status = 0;
                            user.LogoutTime = DateTime.Now;
                        });
                        Growl.InfoGlobal($"用户登出，用户名：{user.NickName},登出时间：{user.LogoutTime}");

                        return;

                    case QuanYiServerBaseClass.DataTypeEnum.Order:
                        ut = Trades.FirstOrDefault(x => x.Guid == QSR.Trade.Guid);
                        if (ut == null & QSR.Trade.UserID != 0 & (QSR.Code == 0 | QSR.Code == 4))
                        {
                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                Trades.Insert(0, QSR.Trade);
                            });
                        }

                        Growl.InfoGlobal($"用户{ut?.UserName}下单，下单信息：{QSR.Trade.ToString()}");
                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.ChangePriceConfirm:
                        ut = Trades.SingleOrDefault(x => x.Guid == QSR.Trade.Guid);
                        decimal oldPrice = ut.Price;
                        if (ut != null)
                        {

                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                ut.Price = QSR.Trade.Price;
                            });
                        }
                        Growl.InfoGlobal($"用户{ut?.UserName}改价，改价信息：将原来的{oldPrice}改为{ut.Price}");
                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.Trade:
                        ut = Trades.SingleOrDefault(x => x.Guid == QSR.Trade.Guid);
                        string tempStatusText = ut.StatusText;
                        if (ut != null)
                        {
                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                ut.Status = QSR.Trade.Status;
                                ut.StatusText = QSR.Trade.StatusText;
                            });

                        }
                        Growl.InfoGlobal($"用户{ut?.UserName}状态变化，改价信息：将原来的{tempStatusText}改为{ut.StatusText}");
                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.Withdrawed:
                        ut = Trades.SingleOrDefault(x => x.Guid == QSR.Trade.Guid);
                        if (ut != null)
                        {

                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                ut.Status = QSR.Trade.Status;
                                ut.StatusText = QSR.Trade.StatusText;
                            });
                        }

                        Growl.InfoGlobal($"用户{ut?.UserName}已撤回交易(Withdrawed)，Trade信息：{ut?.ToString()}");

                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.Withdraw:
                        ut = Trades.SingleOrDefault(x => x.Guid == QSR.Trade.Guid);
                        if (ut != null)
                        {

                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                ut.Status = QSR.Trade.Status;
                                ut.StatusText = QSR.Trade.StatusText;
                            });
                        }
                        Growl.InfoGlobal($"用户{ut?.UserName}撤回交易中(Withdrawing)，Trade信息：{ut?.ToString()}");

                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.BackdatedOrder:
                        ut = Trades.SingleOrDefault(x => x.Guid == QSR.Trade.Guid);
                        if (ut != null)
                        {
                            PrismApplication.Current.Dispatcher.Invoke(() =>
                            {
                                ut.Status = QSR.Trade.Status;
                                ut.StatusText = QSR.Trade.StatusText;
                                ut.Volume = QSR.Trade.Volume;
                                ut.UserTradeID = QSR.Trade.UserTradeID;
                            });
                        }
                        break;
                    case QuanYiServerBaseClass.DataTypeEnum.NewChatMessageIn:

                        HandyControl.Controls.MessageBox.Show("收到客户端用户发来的一条请求");
                        var chatList = QSR.NewChatMessageList;
                        int userId = QSR.UserID;

                        // Check if the UserInfo dictionary contains the userId key
                        string sendInfo = "";
                        if (UserInfo.TryGetValue(userId, out string nickname))
                        {
                            sendInfo = $"发送人：{nickname}";
                        }
                        else
                        {
                            // Handle the case where the userId is not found in the dictionary
                            sendInfo = "发送人：未知"; // "Unknown sender" or another appropriate message
                        }
                        if (chatList != null&& chatList.Count>0)
                        {
                            foreach(var item in chatList)
                            {
                                string chatinfo = $"消息内容：{item.ChatMessageInfo}\r\n" +
                                    $"时间：{item.CreateTime}\r\n" +
                                    $"中介：{item.BrokerName},{sendInfo}";
                                Growl.InfoGlobal($"收到一条新消息：{chatinfo}");
                                await Task.Delay(300);
                            }
                        }

                        Messenger.Default.Send(chatList, MessageToken.SendChatMessage);
                        break;

                    case QuanYiServerBaseClass.DataTypeEnum.RequestReview:

                        HandyControl.Controls.MessageBox.Show("收到客户端用户发来的一条申请复议请求");


                        _dailyData.AddRequestReview(QSR);
                        Growl.InfoGlobal($"收到用户{QSR.Trade.UserName}发来的一条申请复议请求：{QSR.RequestReviewMessage}");

                        break;

                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                AppLog.WriteError(ex.Message + "QuanyiServer" + "Socket_QuanYiClientMessageEvent" + ex.StackTrace);
                _dailyData.BondHelperSysLog(QSR.UserID, "客户端消息，" + ex.Message, QSR.Trade == null ? 0 : QSR.Trade.UserTradeID);
                QSR.Code = 7;
                QSR.Message = ex.Message;
                //serverWebSocketFromClient.SendResponseToClient(QSR);
            }
        }

        /// <summary>
        /// 收到服务端的消息
        /// </summary>
        /// <param name="message"></param>
        private void Adminwebsocket_AdminMessageEvent(string message)
        {
            HandyControl.Controls.MessageBox.Show(message);
        }

        #region 辅助方法
        private string GetGreeting()
        {
            var hour = DateTime.Now.Hour;
            if (hour >= 6 && hour < 12)
            {
                return "早上好，";
            }
            else if (hour >= 12 && hour < 18)
            {
                return "中午好，";
            }
            else
            {
                return "晚上好，";
            }
        }

        private void Greet()
        {
            var greeting = GetGreeting();
            _eventAggregator.GetEvent<MessageEvent>().Publish(new MessageModel()
            {
                Filter = "1",
                Message = "登录成功。" + greeting + LoginViewModel.StaticUserName
            });
        }

        public void RefreshReceivers()
        {
            Receivers = _dailyData.GetChatReceivers();
        }


        /// <summary>
        /// 核心方法，找到窗口然后发送
        /// </summary>
        /// <param name="order"></param>
        private void SendMessage(UserTrade order)
        {

            IntPtr window = FindWindow(null, order.ChatID.Trim());
            //IntPtr TextWindows = IntPtr.Zero;
            //var prc = Process.GetProcessesByName("WeChat.exe");
            if (window != IntPtr.Zero)
            {
                ShowWindow(window, SW_SHOWNORMAL);
                SetForegroundWindow(window);
                //TextWindows = FindTradeWindow(window);
            }
            else
            {
                AppLog.WriteError("未找到可以交易发送中介的窗口" + order.ToString());
                return;
            }

            Task.Delay(10).Wait();

            ChatReceiver chat = null;
            try
            {
                chat = Receivers.Single(x => x.Id == order.ReceiverId);
                if (chat == null)
                {
                    _dailyData.BondHelperSysLog(order.UserID, "Cannot find target receiver", order.UserTradeID);
                    return;
                }
            }
            catch (Exception ex)
            {
                AppLog.WriteError(ex.Message + "PlaceOrderServer" + "SendMessage" + ex.StackTrace);
                return;
            }
            Thread t = new Thread(() => SendMessageToTarget(order.Command));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
        }
        [STAThread]
        private void SendMessageToTarget(string msg)
        {
            Clipboard.SetText(msg);
            //log.Info("Clipboard SetDataObject:", order.Command, "");
            SendKeys.SendWait("^v");
            Task.Delay(10).Wait();
            //log.Info("Command KeyBoard:", "Ctrl+V", "");
            SendKeys.SendWait("{ENTER}");
            //SendKeys.SendWait("{ENTER}");
        }
        #endregion

        #region win32API相关
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32")]
        static extern int SetForegroundWindow(IntPtr hwnd);

        private const int SW_SHOWNORMAL = 1;
        #endregion
    }
}
